//! # Setup - 启动任务管理模块
//!
//! 启动任务管理模块。
//!
//! 通过 [`SETUP_TASKS_MANAGER`] 来添加启动任务。
//!
//! ## 示例
//!
//! ```
//! add_setup_task(|app| { /* 任务 */ }).unwrap();
//! ```

use std::sync::{Arc, Mutex};

use lazy_static::lazy_static;
use tauri::{App, Runtime};

lazy_static! {
    /// Setup 任务管理器
    ///
    /// (S)etup (T)ask (M)anager
    static ref STM: Arc<Mutex<SetupTaskManager>> = Default::default();
}

/// 添加 Setup 任务
///
/// # 参数
///
/// * `task` - Setup 任务
///
/// # 返回值
///
/// * [`Option<()>`] - 成功返回 [`Some(())`]，失败返回 [`None`]
///
/// # 示例
///
/// ```
/// add_setup_task(|app| { /* 任务 */ }).unwrap();
/// ```
pub fn add_setup_task<F>(task: F) -> Option<()>
where
    F: FnOnce(&mut App<tauri::Wry>) -> Result<(), Box<dyn std::error::Error>> + Send + 'static,
{
    STM.lock().ok()?.add_task(task);
    Some(())
}

/// Setup 任务管理器
#[derive(Default)]
struct SetupTaskManager {
    /// Setup 任务列表
    tasks: Vec<
        Box<
            dyn FnOnce(&mut App<tauri::Wry>) -> Result<(), Box<dyn std::error::Error>>
                + Send
                + 'static,
        >,
    >,
}

impl SetupTaskManager {
    /// 添加 Setup 任务
    ///
    /// # 参数
    ///
    /// * `task` - Setup 任务
    fn add_task<F>(&mut self, task: F)
    where
        F: FnOnce(&mut App<tauri::Wry>) -> Result<(), Box<dyn std::error::Error>> + Send + 'static,
    {
        self.tasks.push(Box::new(task));
    }
}

pub trait TauriMP4GameSetup<R: Runtime> {
    /// Setup MP4Game 应用
    fn setup_mp4game(self) -> tauri::Builder<R>;
}

impl TauriMP4GameSetup<tauri::Wry> for tauri::Builder<tauri::Wry> {
    /// Setup MP4Game 应用
    fn setup_mp4game(self) -> tauri::Builder<tauri::Wry> {
        // 取出任务列表
        let tasks = std::mem::replace(&mut STM.lock().unwrap().tasks, vec![]);

        // 执行 Setup 任务
        self.setup(|app| {
            for task in tasks {
                task(app)?;
            }

            Ok(())
        })
    }
}
